﻿namespace TestProject
{
    using System.Diagnostics;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using Swiss;
    using TestProject.TestWrapper_Data;
    using System;
    using System.Reflection;

    /// <summary>
    /// Summary description for UnitTest1
    /// </summary>
    [TestClass]
    public class Profiling_Tests
    {
        public Profiling_Tests()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        private String GetMethodDescription()
        {
            StackFrame fr = new StackFrame(1);
            MethodBase mb = fr.GetMethod();

            //Console.WriteLine(mb.Name);

            DescriptionAttribute da = (DescriptionAttribute)this.GetType().GetMethod(mb.Name).GetCustomAttributes(typeof(DescriptionAttribute), false)[0];

            if (da == null)
            {
                return "Error";
            }

            //Console.WriteLine(da.Description);
            return da.Description;
        }

        #region Profiling

        [Description("Instance - Mark/Add"), TestMethod]
        public void TestInstanceMarkAndAdd()
        {
            String Name = GetMethodDescription();

            using (Profiling pf = new Profiling(Name))
            {
                //Auto Mark

                System.Threading.Thread.Sleep(50);

                Console.WriteLine(pf.Hits());

                //Auto Add
            }

            Console.WriteLine(Profiling.Elapsed(Name));
            Console.WriteLine(Profiling.Hits(Name));
        }


        [Description("Instance - Hits"), TestMethod]
        public void TestInstanceHits()
        {
            String Name = GetMethodDescription();

            using (Profiling pf = new Profiling(Name))
            {
                //Auto Mark

                for (Int32 i = 0; i < 10; i++)
                {
                    Console.WriteLine(pf.Hits());
                }

                //Auto Add
            }

            Console.WriteLine(Profiling.Elapsed(Name));
            Console.WriteLine(Profiling.Hits(Name));
        }

        [Description("Static - Mark/Add"), TestMethod]
        public void TestStaticMarkAndAdd()
        {
            String Name = GetMethodDescription();

            using (new Profiling())
            {
                //Manual Mark
                Profiling.Mark(Name);

                System.Threading.Thread.Sleep(50);

                //Manual Add
                Profiling.Add(Name);
            }

            Console.WriteLine(Profiling.Elapsed(Name));
            Console.WriteLine(Profiling.Hits(Name));
        }

        [Description("Static - Mark/Add Loop"), TestMethod]
        public void TestStaticMarkAndAddLoop()
        {
            String Name = GetMethodDescription();

            using (new Profiling())
            {
                for (Int32 i = 0; i < 10; i++)
                {
                    Profiling.Mark(Name);

                    System.Threading.Thread.Sleep(50);

                    Profiling.Add(Name);
                }

                Console.WriteLine(Profiling.Elapsed(Name));
                Console.WriteLine(Profiling.Hits(Name));
            }
        }

        [Description("Static - Timing Still Present"), TestMethod]
        public void TestStillPresent()
        {
            //Note: We need an instance because IEnumerable cannot be implemented in a static class.
            foreach (String Profile in new Profiling())
            {
                Console.WriteLine("{0} - {1} Hit(s) - {2}", Profiling.Elapsed(Profile), Profiling.Hits(Profile), Profile);
            }
        }

        [Description("Mixed - Mark/Add Loop"), TestMethod]
        public void TestMixedMarkAndAddLoop()
        {
            String Name = GetMethodDescription();

            using (Profiling pf = new Profiling(Name))
            {
                for (Int32 i = 0; i < 10; i++)
                {
                    Profiling.Mark(Name);

                    System.Threading.Thread.Sleep(50);

                    pf.Add();
                }

                Console.WriteLine(Profiling.Elapsed(Name));
                Console.WriteLine(Profiling.Hits(Name));
            }
        }

        [Description("Static - Hit Loop"), TestMethod]
        public void TestStaticHitLoop()
        {
            String Name = GetMethodDescription();

            using (new Profiling())
            {
                for (Int32 i = 0; i < 10; i++)
                {
                    Profiling.Hit(Name);
                }

                Console.WriteLine(Profiling.Elapsed(Name));
                Console.WriteLine(Profiling.Hits(Name));
            }
        }
        #endregion Profiling
    }
}
